package com.youdianstar.app.ui


import androidx.databinding.ObservableField
import androidx.lifecycle.viewModelScope

import com.youdianstar.app.support.ApiRepository
import com.youdianstar.app.ui.help.FaqListActivity
import com.youdianstar.app.common.*
import com.youdianstar.app.common.base.BaseViewModel
import com.youdianstar.app.common.bind.command.BindingAction
import com.youdianstar.app.common.bind.command.BindingCommand
import com.youdianstar.app.common.entity.*
import com.youdianstar.app.common.event.EventLiveData
import com.youdianstar.app.common.event.NetStateLiveData
import com.youdianstar.app.common.util.DateUtil
import com.youdianstar.app.entity.*
import com.youdianstar.app.ui.op.MerchantCenterActivity
import com.youdianstar.app.ui.pay.WalletActivity
import com.youdianstar.app.util.DataAppManager
import com.youdianstar.app.common.ex.toJson
import com.youdianstar.app.ui.reward.InviteActivity
import com.youdianstar.app.ui.reward.PointPlanActivity
import com.youdianstar.app.ui.reward.RewardHomeActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch


/**
 * File: MainViewModel
 * Author: 82149 Create: 2021/9/25 15:33
 * Changes (from 2021/9/25)
 * --------------------------------------------------
 * description:
 * ---------------------------------------------------
 *
 */
class MainViewModel(private val repo: ApiRepository) : BaseViewModel() {
    val closeDrawerEvent = EventLiveData<Boolean>()

    val drawerBgAction = BindingCommand<Any>(BindingAction {
        //侧边栏--背景点击事件 ,不处理
        //closeDrawerEvent.postValue("")
    })

    val historyAction = BindingCommand<Any>(BindingAction {
        //侧边栏--租借订单记录
        startActivity<OrderListActivity>()
    })

    val walletViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--钱包 (已屏蔽，因为没有绑定银行卡的需求)
        // DataAppManager.instance.rentScanTag = false
        // startActivity<WalletActivity>()
    })

    val chargingCardViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--充电卡
//        startActivity<ChargeListActivity>()
    })

    val rewardViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--优惠券
        startActivity<RewardHomeActivity>()
    })

    val pointViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--积分
        startActivity<PointPlanActivity>()
    })

    val inviteViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--邀请(已屏蔽)
        // startActivity<InviteActivity>()
    })

    val businessViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--招商加盟
        startActivity<BusinessJoinActivity>()
    })

    val helpViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--Faq列表
        startActivity<FaqListActivity>()
    })

    val settingsViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--设置
        startActivity<SettingActivity>()
    })

    val opMerchantViewAction = BindingCommand<Any>(BindingAction {
        //侧边栏--商户中心
        // TODO: 测试阶段 - 商户中心功能已开启，所有用户都可以访问
        // 正式发布时需要根据用户权限进行访问控制
        startActivity<MerchantCenterActivity>()
    })

    val rentFailAction = BindingCommand<Any>(BindingAction {
        //订单上报--订单租借失败
        orderDataFiled.get()?.let {
            val penaltyAmount :Float = it.billing?.penaltyAmount?:0.0F
            startActivity<ReportSearchActivity>(Extra.IT_ORDERNO to it.orderNo,
                Extra.IT_TYPE to BisType.Report_RentFailed, Extra.IT_MONEY to penaltyAmount)
        }
    })

    val returnFailAction = BindingCommand<Any>(BindingAction {
        //订单上报--订单归还
        orderDataFiled.get()?.let {
            val penaltyAmount :Float = it.billing?.penaltyAmount?:0.0F
            startActivity<ReportSearchActivity>(Extra.IT_ORDERNO to it.orderNo,
                Extra.IT_TYPE to BisType.Report_ReturnFailed, Extra.IT_MONEY to penaltyAmount)
        }
    })

    val reportFaultAction = BindingCommand<Any>(BindingAction {
        //订单上报--订单报损
        orderDataFiled.get()?.let {
            startActivity<ReportFaultActivity>(Extra.IT_ORDERNO to it.orderNo)
        }
    })

    val reportLossAction = BindingCommand<Any>(BindingAction {
        //订单上报--订单报失
        orderDataFiled.get()?.let {
            val penaltyAmount :Float = it.billing?.penaltyAmount?:0.0F
            startActivity<ReportLossActivity>(Extra.IT_ORDERNO to it.orderNo, Extra.IT_MONEY to penaltyAmount,  Extra.IT_DATA to it.toJson())
        }
    })

    /**---------------------------接口 获取配置/用户登出/判断租借--------------------------*/

    val configResultLiveData = NetStateLiveData<List<ConfigItem>>()
    fun getSystemConfig(){
        viewModelScope.launch(Dispatchers.IO) {
            repo.getSystemConfig(configResultLiveData)
        }
    }

    val versionUpdateLiveData = NetStateLiveData<VersionUpdate>()
    /**
     * 判断App版本号
     * --强制更新版本
     */
    fun checkVersionUpdate(localVer:String){
        viewModelScope.launch (Dispatchers.IO){
            repo.checkVersionUpdate(localVer, netVer = "1.0.0" ,versionUpdateLiveData)
        }
    }


    val userResultLiveData = NetStateLiveData<UserInfo>()
    val userCenterResultLiveData = NetStateLiveData<UserCenterResponse>() // 新增：用于获取用户中心完整数据
    /**
     * 获取用户信息
     * @param isShow 是否显示loading
     */
    fun getAccount(isShow: Boolean = true){
        if (isShow)
            showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.getUserCenter(userCenterResultLiveData)
        }
    }

    val merchantLinkLiveData = NetStateLiveData<MerchantLink>()
    /**
     * 店主入住--邀请链接绑定
     *
     * @param ciphertext 加密文本
     */
    fun linkMerchantAccount(ciphertext:String){
        showLoading()
        viewModelScope.launch (Dispatchers.IO){
            repo.merchantLinkAction(ciphertext ,merchantLinkLiveData)
        }
    }

    val redeemInviteResultData = NetStateLiveData<Any>()
    /**
     * 邀请-兑换邀请码
     *
     * @param code 邀请码
     */
    fun redeemInvitationCode(code:String){
        viewModelScope.launch(Dispatchers.IO) {
            repo.redeemInvitationCode(code,redeemInviteResultData)
        }
    }

    val redeemRewardResultData = NetStateLiveData<Any>()
    /**
     * 充电卡/优惠券/优惠码扫码-兑换
     *
     * @param code 码
     */
    fun redeemRewardCode(typeTx:String,code:String){
        val typeValue = when(typeTx){
            "1" -> 1
            "2" -> 2
            else -> 3
        }
        viewModelScope.launch(Dispatchers.IO) {
            repo.scanRewardCode(typeValue, code, redeemRewardResultData)
        }
    }

    /**---------------------------获取网点--------------------------*/

    val branchListResultData = NetStateLiveData<List<Any>>()

    fun getMapBranchList(lat: Double, lng: Double){
        android.util.Log.d("MainViewModel", "getMapBranchList: lat=$lat, lng=$lng")
        viewModelScope.launch (Dispatchers.IO){
            // 传入API的顺序：lat, lng
            repo.getMapBranchList(lat, lng, branchListResultData)
        }
    }

    /**---------------------------订单轮询--------------------------*/

    val orderDataFiled = ObservableField<OrderInfo>()
    val queryResultData = NetStateLiveData<OrderQuery>()
    //标记是否请求
    var isRentingQuest = false
    /**
     * 获取租借订单
     */
    private fun getRentingOrder(){
        if (isRentingQuest)
            return
        isRentingQuest = true
        viewModelScope.launch (Dispatchers.IO){
            repo.getRentingOrder(queryResultData)
        }
    }

    //UI 时长计时 单位毫秒
    var distanceTime = 0L
    val orderTimeFiled = ObservableField<String>()


    var requestJob : Job? =null

    /**
     * 使用Flow 实现轮训计时 : 15秒一次 - 已注释
     */
    fun countOrderRequest(){
        // 轮询已注释，避免刷log
        /*
        requestJob?.cancel()
        requestJob = flow {
            for (i in 0..MAX_COUNT_ORDER){
                emit(i)
                delay(MIN_COUNT_LIMIT)
            }
        }.flowOn(Dispatchers.Default)
            .onCompletion {
                //Job cancel 会走这里
            }
            .onEach {
                //requestCountEvent.value = it
                getRentingOrder()
            }
            .flowOn(Dispatchers.Main)
            .launchIn(viewModelScope)
        */
    }


    var countJob : Job? =null
    /**
     * 使用Flow 实现计时 : 1秒一次
     */
    fun countOrderTime(){
        countJob?.cancel()
        countJob = flow{
            for (i in 0..MAX_COUNT_ORDER){
                emit(i)
                delay(1000)
            }
        }.flowOn(Dispatchers.Default)
            .onCompletion {
                // timeCountEvent.value = -1 //countJob cancel 会走这里
            }
            .onEach {
                distanceTime += 1000
                //更新UI
                orderTimeFiled.set(DateUtil.time2textTime(distanceTime))
            }
            .flowOn(Dispatchers.Main)
            .launchIn(viewModelScope)
    }

}